package Simplex;

import java.text.DecimalFormat;
import java.util.Scanner;

/**
 *
 * @author Alexandre
 * @author Guilherme
 * @autor Murillo
 */
public class Maximiza {

    /**
     * Maximiza a matriz passo a passo
     */
    public void maximizar() { //Se entra e sai for igual -1 ignora
        int entra = -1;
        int sai = -1;
        Scanner scan = new Scanner(System.in);
        double menorEntra = 0; //Variável auxiliar que recebe o menor valor da linha base
        double menorSai = Integer.MAX_VALUE; //Váriavel auxiliar que recebe o menor valor da divisão da coluna base pela coluna que entra na bases

        //Encontrando a variável que entra na base
        for (int i = 0; i < Main.colunas - 1; i++) {
            if (Main.Matriz[0][i] < menorEntra) {
                menorEntra = Main.Matriz[0][i];
                entra = i;
            }
        }

        if (entra != -1) {
            System.out.println("X" + entra + " entra na base");
        }

        //Verifica se encontrou a solução ótima
        if (menorEntra == 0) {
            System.out.println("Fim da maximizacao");
            System.out.println("Quadro Final");
            show();
            System.out.println("Resultado:");
            System.out.println("Z = " + Main.Matriz[0][Main.colunas - 1]);
            for (int i = 0; i < Main.sizeBase; i++) {
                System.out.println("X" + Main.base[i] + " = " + Main.Matriz[i + 1][Main.colunas - 1] + "\t");
            }
            System.out.println("");

            int cont = 0;

            //Verificando se existem multiplas soluções
            for (int i = 0; i < Main.colunas - 1; i++) {
                if (Main.Matriz[0][i] == 0) {
                    ++cont;
                }
            }
            if (cont > Main.sizeBase) { // tem soluções múltiplas, se tiver mais variáveis zeradas do que o tamanho da base
                System.out.println(cont);
                System.out.println("Existem multiplas solucoes");
                System.out.println("Buscar outra solução? (0 = Nao, 1 = Sim)");
                int op = scan.nextInt();
                if (op == 1) {
                    //buscando a variável para entrar
                    for (int i = 0; i < Main.colunas - 1; i++) {

                        cont = 0; //zerando o contador

                        //verifica se a variável já está na base
                        for (int j = 0; j < Main.sizeBase; j++) {
                            if (i == Main.base[j]) {
                                ++cont; //se estiver na base, incrementa o contador
                            }
                        }

                        //Se não estiver na base e for 0, entra na base
                        if (cont == 0 && Main.Matriz[0][i] == 0) {
                            entra = i;
                            System.out.println("X" + entra + " entra na base");
                            break; //Sai do for e continua a operar com o novo valor que entra
                        }

                    }

                } else { //Não quer ver outra solução, termina
                    return;
                }
            } else { // Não tem mais soluções, termina
                return;
            }
        }

        int aux = -1;//Usado para imprimir a variável que sai da base
        //Encontrando a variável que sai na base
        for (int i = 1; i < Main.linhas; i++) {
            if (Main.Matriz[i][Main.colunas - 1] > 0 && Main.Matriz[i][entra] > 0) {
                if ((Main.Matriz[i][Main.colunas - 1] / Main.Matriz[i][entra]) < menorSai) {
                    menorSai = (Main.Matriz[i][Main.colunas - 1] / Main.Matriz[i][entra]);
                    sai = i;
                    aux = Main.base[sai - 1]; //Armazena no vetor temporário para impressão
                }
            }
        }
        Main.base[sai - 1] = entra; // coloca a variável que entra no lugar da variável que sai da base

        if (sai != -1) {
            System.out.println("X" + aux + " sai da base");
        } else {
            System.out.println("Ninguem sai da base, fim");
            return;
        }

        //Começando o pivoteamento
        double fator;
        fator = Main.Matriz[sai][entra];

        for (int i = 0; i < Main.colunas; i++) {
            Main.Matriz[sai][i] /= fator;
        }

        for (int i = 0; i < Main.linhas; i++) {
            if (i != sai) {
                fator = Main.Matriz[i][entra] * -1; //Calcula o fator de multiplicação de cada linha
                if (fator != 0) { //Se for 0 não faz nada
                    for (int j = 0; j < Main.colunas; j++) {
                        Main.Matriz[i][j] += fator * Main.Matriz[sai][j];
                    }
                }
            }
        }

        ++Main.quadro; //Incrementa o número do quadro
        System.out.println("\nQuadro " + Main.quadro); //Imprime o número do quadro
        show(); //Imprime a matriz
        maximizar(); //Próximo passo da maximização
    }

    /**
     * Imprime a matriz
     */
    public void show() {
        Scanner scan = new Scanner(System.in);
        DecimalFormat df = new DecimalFormat("0.00");//Usado para imprimir somente 2 valores após a vírgula

        for (int i = 0; i < Main.colunas - 1; i++) {
            System.out.print("\tX" + i);
        }
        System.out.println("\tb");
        for (int i = 0; i < Main.linhas; i++) {
            if (i == 0) {
                System.out.print("Base\t");
            } else {
                System.out.print("X" + Main.base[i - 1] + "\t");
            }
            for (int j = 0; j < Main.colunas; j++) {
                System.out.print(df.format(Main.Matriz[i][j]) + "\t");
            }
            System.out.println("");
        }

        System.out.println("Pressione uma tecla para continuar...");
        String pause = scan.nextLine();
    }
}
